package com.cskaoyan.service.wx_coupon;

import com.cskaoyan.bean.goods.Goods;
import com.cskaoyan.bean.goods.GoodsExample;
import com.cskaoyan.bean.goods.GoodsProduct;
import com.cskaoyan.bean.promote.Coupon;
import com.cskaoyan.bean.promote.CouponUserExample;
import com.cskaoyan.bean.user.User;
import com.cskaoyan.bean.wx_cart.Cart;
import com.cskaoyan.bean.wx_cart.CartExample;
import com.cskaoyan.bean.wx_coupon.*;
import com.cskaoyan.bean.wx_coupon.vo.WxCouponMyListVo;
import com.cskaoyan.mapper.goods.GoodsMapper;
import com.cskaoyan.mapper.goods.GoodsProductMapper;
import com.cskaoyan.mapper.mall.CategoryMapper;
import com.cskaoyan.mapper.promote.CouponMapper;
import com.cskaoyan.mapper.promote.CouponUserMapper;
import com.cskaoyan.mapper.wx_cart.CartMapper;
import com.cskaoyan.mapper.wx_coupon.WxCouponMapper;
import com.cskaoyan.mapper.wx_coupon.WxCouponUserMapper;
import com.cskaoyan.utils.StringUtils;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.apache.bcel.classfile.Code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.text.resources.FormatData;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: Jason 805636901@qq.com
 * @create: 2021-10-22-10:34 AM
 */
@Service
public class WxCouponServiceImpl implements WxCouponService {

    @Autowired
    WxCouponMapper wxcouponMapper;
    @Autowired
    WxCouponUserMapper wxCouponUserMapper;
    @Resource
    CartMapper cartMapper;
    @Resource
    GoodsMapper goodsMapper;
    @Resource
    GoodsProductMapper goodsProductMapper;
    @Resource
    CategoryMapper categoryMapper;

    @Override
    public WxCouponPageData queryWxCouponList(Integer page, Integer limit) {
        //开启分页
        PageHelper.startPage(page, limit);
        WxCouponExample example = new WxCouponExample();
        WxCouponExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andStatusEqualTo((short) 0);

        //if (limit != null && !"".equals(limit)) {
        //    example.setOrderByClause("id asc limit " + limit);
        //}
        List<WxCouponVo> wxCouponVos = wxcouponMapper.Custom_selectByExample(example);
        return WxCouponPageData.ok(wxCouponVos);
    }


    //TODO 获取userId只查询对于userId下的优惠券.
    @Override
    public WxCouponMyListVo queryMyCouponBySatus(int status, int page, Integer id) {

        List<WxCouponInfo> wxCouponInfos = wxcouponMapper.selectMyCouponInfos(status, id);
        for (WxCouponInfo wxCouponInfo : wxCouponInfos) {
            wxCouponInfo.setAvailable(false);
        }
        WxCouponMyListVo wxCouponMyListVo = new WxCouponMyListVo();
        wxCouponMyListVo.setTotal(wxCouponInfos.size());
        wxCouponMyListVo.setPages(wxCouponInfos.size() / page);
        wxCouponMyListVo.setPage(page);
        wxCouponMyListVo.setList(wxCouponInfos);
        return wxCouponMyListVo;

    }

    @Override
    public WxCouponMyListVo queryMyAvailableCoupon(Integer id) {
        List<WxCouponInfo> wxCouponInfos = wxcouponMapper.selectMyAvailableCouponInfos(id);
        WxCouponMyListVo wxCouponMyListVo = new WxCouponMyListVo();
        wxCouponMyListVo.setList(wxCouponInfos);
        return wxCouponMyListVo;
    }

    @Transactional
    @Override
    public int validCode(String code, Integer id) {

        int firstStep = wxcouponMapper.valid(code);

        //TODO:校验后拿到CouponId
        WxCouponUser couponUser = new WxCouponUser();
        //验证成功后,在market_goods_user中插入一条数据
        couponUser.setUserId(id);
        couponUser.setCouponId(1); //暂时写死.

        Date startTime = new Date();
        Calendar c = Calendar.getInstance();
        Date endTime = new Date();

        c.setTime(startTime);
        c.add(Calendar.DATE, 3); //截至日期为3天后
        endTime = c.getTime();

        couponUser.setStartTime(startTime);
        couponUser.setEndTime(endTime);


        couponUser.setStatus((short) 0);
        int secondStep = wxCouponUserMapper.insertSelective(couponUser);
        return secondStep;
    }

    @Override
    public WxCoupon findById(Integer id) {
        return wxcouponMapper.selectByPrimaryKey(id);
    }

    /**
     * 这里只做优惠券的逻辑
     * 按类型分，其实只是按二级目录分，这里写得是按全部的类型（含父类型）来分
     *
     * @param cartId
     * @param grouponRulesId
     * @return
     */
    @Override
    public List<WxCouponInfo> queryMyAvailableCoupon1(Integer cartId, Integer grouponRulesId) {
        //取出用户的id
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        Integer UserId = user.getId();

        //拿用户所有的未过期、未使用的优惠券
        WxCouponUserExample couponUserExample = new WxCouponUserExample();
        WxCouponUserExample.Criteria couponUserExampleCriteria = couponUserExample.createCriteria();
        couponUserExampleCriteria.andDeletedEqualTo(false);
        couponUserExampleCriteria.andStartTimeLessThanOrEqualTo(new Date());
        couponUserExampleCriteria.andEndTimeGreaterThanOrEqualTo(new Date());
        couponUserExampleCriteria.andStatusEqualTo((short) 0);
        List<WxCouponUser> wxCouponUsers = wxCouponUserMapper.selectByExample(couponUserExample);

        //拿用户优惠券对应的优惠券规则
        LinkedList<Integer> couponId = new LinkedList<>();
        for (WxCouponUser wxCouponUser : wxCouponUsers) {
            couponId.add(wxCouponUser.getCouponId());
        }
        List<WxCoupon> wxCoupons = new LinkedList<>();
        if (couponId.size() != 0) {
            WxCouponExample wxCouponExample = new WxCouponExample();
            WxCouponExample.Criteria wxCouponExampleCriteria = wxCouponExample.createCriteria();
            wxCouponExampleCriteria.andIdIn(couponId);
            wxCoupons = wxcouponMapper.selectByExample(wxCouponExample);
        }

        //在购物车中下单和快速下单分开处理
        List<Cart> carts;
        if (cartId == 0) {
            //在购物车中下单
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andUserIdEqualTo(UserId);
            criteria.andCheckedEqualTo(true);
            criteria.andDeletedEqualTo(false);
            carts = cartMapper.selectByExample(cartExample);
        } else {
            //快速下单
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andIdEqualTo(cartId);
            carts = cartMapper.selectByExample(cartExample);
        }

        //订单总价
        BigDecimal OrderPrice = new BigDecimal(0);
        HashMap<Integer, BigDecimal> categoryAndPriceMap = new HashMap<>();
        HashMap<Integer, BigDecimal> goodsTypeAndPriceMap = new HashMap<>();
        for (Cart cart : carts) {
            Integer type = goodsMapper.selectByPrimaryKey(cart.getGoodsId()).getCategoryId();
            BigDecimal price = cart.getPrice().multiply(new BigDecimal(cart.getNumber()));
            OrderPrice = OrderPrice.add(price);
            while (!type.equals(0)) {

                if (categoryAndPriceMap.containsKey(type)) {
                    categoryAndPriceMap.put(type, categoryAndPriceMap.get(type).add(price));
                } else {
                    categoryAndPriceMap.put(type, price);
                }
                type = categoryMapper.selectByPrimaryKey(type).getPid();
            }
            Integer goodsId = cart.getGoodsId();
            if (goodsTypeAndPriceMap.containsKey(cart.getGoodsId())) {
                goodsTypeAndPriceMap.put(goodsId, goodsTypeAndPriceMap.get(goodsId).add(price));
            } else {
                goodsTypeAndPriceMap.put(goodsId, price);
            }
        }


        //查看商品、商品类型是否有对应优惠券
        LinkedList<WxCoupon> availableCouponList = new LinkedList<>();
        for (WxCoupon wxCoupon : wxCoupons) {
            Short type = wxCoupon.getGoodsType();
            String[] goodsValue = StringUtils.string2StringArrays(wxCoupon.getGoodsValue());
            switch (type) {
                case (short) 0:
                    if (wxCoupon.getMin().compareTo(OrderPrice) <= 0) {
                        availableCouponList.add(wxCoupon);
                    }
                    break;
                case (short) 1:
                    for (String s : goodsValue) {
                        Integer goodsType = Integer.valueOf(s);
                        if (categoryAndPriceMap.containsKey(goodsType) && categoryAndPriceMap.get(goodsType).compareTo(wxCoupon.getMin()) >= 0) {
                            availableCouponList.add(wxCoupon);
                        }
                    }
                    break;
                case (short) 2:
                    for (String s : goodsValue) {
                        Integer goodsId = Integer.valueOf(s);
                        if (goodsTypeAndPriceMap.containsKey(goodsId) && goodsTypeAndPriceMap.get(goodsId).compareTo(wxCoupon.getMin()) >= 0) {
                            availableCouponList.add(wxCoupon);
                        }
                    }
            }
        }

        //把查到的优惠券加到list中，（先按金额排序，后按过期时间排序）
        LinkedList<WxCouponInfo> wxCouponInfos = new LinkedList<>();
        for (WxCoupon wxCoupon : availableCouponList) {
            for (WxCouponUser wxCouponUser : wxCouponUsers) {
                if (wxCoupon.getId().equals(wxCouponUser.getCouponId())) {
                    WxCouponInfo wxCouponInfo = new WxCouponInfo();
                    wxCouponInfo.setMin(wxCoupon.getMin().doubleValue());
                    wxCouponInfo.setName(wxCoupon.getName());
                    //激活状态怎么判断
                    wxCouponInfo.setAvailable(true);
                    wxCouponInfo.setDiscount(wxCoupon.getDiscount().doubleValue());
                    wxCouponInfo.setId(wxCouponInfo.getId());
                    Date startTime = wxCouponUser.getStartTime();
                    Date endTime = wxCouponUser.getEndTime();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    wxCouponInfo.setStartTime(simpleDateFormat.format(startTime));
                    wxCouponInfo.setTag(wxCoupon.getTag());
                    wxCouponInfo.setEndTime(simpleDateFormat.format(endTime));
                    wxCouponInfo.setCid(wxCoupon.getId());
                    wxCouponInfo.setDesc(wxCoupon.getDesc());
                    wxCouponInfos.add(wxCouponInfo);
                }
            }
        }
        //排序
        wxCouponInfos.sort(((o1, o2) -> {
            int i;
            if ((i = (int) (o2.getDiscount() - o1.getDiscount())) == 0) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    return simpleDateFormat.parse(o1.getEndTime()).compareTo(simpleDateFormat.parse(o2.getEndTime()));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            return i;
        }));
        return wxCouponInfos;
    }
}
